package com.dhcc.bpm.modules.scf.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dhcc.bpm.common.segmentId.LocalCacheIdGenerator;
import com.dhcc.bpm.modules.scf.dto.ScfRenewableInInfoDTO;
import com.dhcc.bpm.modules.scf.entity.ScfOperationLogInfo;
import com.dhcc.bpm.modules.scf.entity.ScfRenewableInInfo;
import com.dhcc.bpm.modules.scf.entity.SelectEntity.RenewableInByPayment;
import com.dhcc.bpm.modules.scf.enumUtil.ScfOperationLogInfoEnum;
import com.dhcc.bpm.modules.scf.mapper.*;
import com.dhcc.bpm.modules.scf.service.IScfFileAttachmentInfoService;
import com.dhcc.bpm.modules.scf.service.IScfOperationLogInfoService;
import com.dhcc.bpm.modules.scf.service.IScfRenewableInInfoService;
import com.dhcc.bpm.modules.scf.util.ExcelUtil;
import com.dhcc.bpm.modules.scf.util.MD5Utils;
import com.dhcc.bpm.modules.scf.util.OBSUtil;
import com.dhcc.bpm.modules.scf.vo.ScfContractInfoVO.ScfGetContractDetailsVO;
import com.dhcc.bpm.modules.scf.vo.ScfDriverInfoVO.ScfGetDriverDetailsVO;
import com.dhcc.bpm.modules.scf.vo.ScfFileAttachmentInfoVO.ScfFileAttachmentInfoVO;
import com.dhcc.bpm.modules.scf.vo.ScfRenewableInInfoVO.ScfGetRenewableInDetailsVO;
import com.dhcc.bpm.modules.scf.vo.ScfRenewableInInfoVO.ScfGetRenewableInListVO;
import com.dhcc.bpm.modules.scf.vo.ScfSubjectBasicInfoVO.ScfGetSubjectDetailsVO;
import com.dhcc.bpm.modules.system.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 再生资源入库单服务实现类
 *
 * @author liuguoting
 * @since 2023-09-22
 */
@Service
@Slf4j
public class ScfRenewableInInfoServiceImpl extends ServiceImpl<ScfRenewableInInfoMapper, ScfRenewableInInfo> implements IScfRenewableInInfoService {

    /**
     * 文件附件service接口
     */
    @Autowired
    private IScfFileAttachmentInfoService scfFileAttachmentInfoService;
    /**
     * id生成器
     */
    @Autowired
    private LocalCacheIdGenerator localCacheIdGenerator;
    /**
     * 操作日志service接口
     */
    @Autowired
    private IScfOperationLogInfoService scfOperationLogInfoService;
    /**
     * 合同信息mapper接口
     */
    @Autowired
    private ScfContractInfoMapper scfContractInfoMapper;
    /**
     * 主体信息mapper接口
     */
    @Autowired
    private ScfSubjectBasicInfoMapper scfSubjectBasicInfoMapper;
    /**
     * 支付回单信息mapper接口
     */
    @Autowired
    private ScfPaymentInfoMapper scfPaymentInfoMapper;
    /**
     * 司机信息mapper接口
     */
    @Autowired
    private ScfDriverInfoMapper scfDriverInfoMapper;
    /**
     * 用户信息service接口
     */
    @Autowired
    private IUserService userService;
    /**
     * 华为obs对象存储工具类
     */
    @Autowired
    private OBSUtil obsUtil;


    /**
     * 再生资源入库单分页列表查询
     *
     * @param page
     * @param scfRenewableInInfo
     * @return
     */
    @Override
    public IPage<ScfGetRenewableInListVO> selectScfRenewableInInfoPage(IPage<ScfGetRenewableInListVO> page, ScfRenewableInInfoDTO scfRenewableInInfo) {
        List<ScfGetRenewableInListVO> scfGetRenewableInListVOS;
        // 判断是否查询未关联记录列表
        String isRelated = scfRenewableInInfo.getIsRelated();
        if (isRelated != null && isRelated.equals("3")) {
            // 获取再生资源入库列表信息--未关联的
            scfGetRenewableInListVOS = baseMapper.selectUnrelatedRecords(page, scfRenewableInInfo);
        } else {
            // 获取再生资源入库列表信息--全部
            scfGetRenewableInListVOS = baseMapper.selectScfRenewableInInfoPage1(page, scfRenewableInInfo);
        }
        // 判断列表是否为空
        if (scfGetRenewableInListVOS.size() != 0) {
            // 循环遍历每一条记录
            for (ScfGetRenewableInListVO scfGetRenewableInListVO : scfGetRenewableInListVOS) {
                // 获取合同记录的 rowId
                String contractRowId = scfContractInfoMapper.selectRowIdByContractNum(scfGetRenewableInListVO.getContractNum() ,scfRenewableInInfo.getOrgCode());
                // 根据合同记录的 rowId 获取到合同的详细数据
                ScfGetContractDetailsVO details = scfContractInfoMapper.getDetails(contractRowId);
                if(details != null ){
//                    scfGetRenewableInListVO.setCorrelation(1);
                    // 获取再生资源主体详细数据
                    ScfGetSubjectDetailsVO scfSubjectBasicInfoMapperDetailsRenewable = scfSubjectBasicInfoMapper.getDetails(details.getPartyANum());
                    // 获取供应商主体详细数据
                    ScfGetSubjectDetailsVO scfSubjectBasicInfoMapperDetailsSupplierName = scfSubjectBasicInfoMapper.getDetails(details.getPartyBNum());
                    if(scfSubjectBasicInfoMapperDetailsSupplierName!=null  &&  scfSubjectBasicInfoMapperDetailsSupplierName!=null ){
                        // 拿到再生资源主体详细数据中的主体名称设置给再生入库单中的再生资源名称字段
                        scfGetRenewableInListVO.setRenewableName(scfSubjectBasicInfoMapperDetailsRenewable.getSubName());
                        // 拿到供应商主体详细数据中的主体名称设置给再生入库单中的供应商名称字段
                        scfGetRenewableInListVO.setSupplierName(scfSubjectBasicInfoMapperDetailsSupplierName.getSubName());
                    }
                }
/*                else{
                    scfGetRenewableInListVO.setCorrelation(0);
                }*/


            }
        }
        return page.setRecords(scfGetRenewableInListVOS);
    }

    /**
     * 再生资源入库单详情查询
     *
     * @param scfRenewableInInfo
     * @return
     */
    @Override
    public ScfGetRenewableInDetailsVO getDetails(ScfRenewableInInfoDTO scfRenewableInInfo) {
        ScfGetRenewableInDetailsVO detail = baseMapper.getDetails(scfRenewableInInfo.getRowId());
        if (detail != null) {
            // 获取与文件附件表关联的id
            String rowIds = detail.getRowId();
            // 根据根据合同编号获取合同rowId
            String contractRowId = scfContractInfoMapper.selectRowIdByContractNum(detail.getContractNum()  ,scfRenewableInInfo.getOrgCode());
            if(contractRowId !=null){
                // 获取合同详细信息
                ScfGetContractDetailsVO detailsContract = scfContractInfoMapper.getDetails(contractRowId);
                // 从合同中获取再生及供应商主体编号并查询主体信息
                ScfGetSubjectDetailsVO scfSubjectBasicInfoMapperDetailsRenewable = scfSubjectBasicInfoMapper.getDetails(detailsContract.getPartyANum());
                ScfGetSubjectDetailsVO scfSubjectBasicInfoMapperDetailsSupplierName = scfSubjectBasicInfoMapper.getDetails(detailsContract.getPartyBNum());
                if(scfSubjectBasicInfoMapperDetailsRenewable!=null && scfSubjectBasicInfoMapperDetailsSupplierName !=null ){
                    // 从主体信息中拿到主体名称并赋值
                    detail.setRenewableName(scfSubjectBasicInfoMapperDetailsRenewable.getSubName());
                    detail.setSupplierName(scfSubjectBasicInfoMapperDetailsSupplierName.getSubName());
                    // 司机驾驶证号再去查询司机的详细信息

                }
            }

            String driverRowId = scfDriverInfoMapper.selectRowIdByLicense(detail.getLicense());
            if(driverRowId!=null ){
                ScfGetDriverDetailsVO scfDriverInfoMapperDetails = scfDriverInfoMapper.getDetails(driverRowId);
                // 取出司机姓名及司机联系方式并设置给入库单详情中
                detail.setDriverName(scfDriverInfoMapperDetails.getDriverName());
                detail.setDriverMobile(scfDriverInfoMapperDetails.getMobile());
            }

            // 查询再生入库与支付回单的关联关系数组
            List<RenewableInByPayment> renewableInByPayments = baseMapper.selectRenewableInByPayment(detail.getRenewableInNum());
            // 判断关联关系是否为空
            if (renewableInByPayments != null) {
                for (RenewableInByPayment renewableInByPayment : renewableInByPayments) {
                    // 根据支付回单号查询支付回单的剩余金额
                    BigDecimal remainAmountByPaymentNum = scfPaymentInfoMapper.selectZsrkRemainAmountByPaymentNum(renewableInByPayment.getPaymentNum());
                    // 设置剩余金额
                    renewableInByPayment.setRemainAmount(remainAmountByPaymentNum);
                    renewableInByPayment.setZsrkRemainAmount( remainAmountByPaymentNum );
                }
            }
            detail.setRenewableInByPayments(renewableInByPayments);
            // 查询关联的附件信息
            List<ScfFileAttachmentInfoVO> scfFileAttachmentInfoVOS = scfFileAttachmentInfoService.selectAllByAssociationId(rowIds);
            // 将附件信息存进dto里
            detail.setFileAttachmentInfoVOS(scfFileAttachmentInfoVOS);
        }
        return detail;
    }

    /**
     * 再生资源入库单新增
     *
     * @param scfRenewableInInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveRemewableInInfo(ScfRenewableInInfoDTO scfRenewableInInfo) throws Exception {
        // 判断是否已存在该再生入库单号码
        String renewableInNum = scfRenewableInInfo.getRenewableInNum();
        String rowIdByRenewableInNum = baseMapper.selectRowIdByRenewableInNum(renewableInNum);
        if (rowIdByRenewableInNum != null) {
            // 说明该再生入库单号码库中存在，抛出异常，提示该再生入库单已存在
            throw new IllegalArgumentException("再生企业入库单:" + renewableInNum + "已存在，请勿重复录入再生企业入库单！");
        }
        // 生成日期
        SimpleDateFormat date = new SimpleDateFormat("YYYYMMdd");
        String formatdate = date.format(new Date());
        // 生成时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
        String formTime = timeFormat.format(new Date());
        // 生成ROW_ID
        // 开始补充对象字段start
        // 设置记录编号
        scfRenewableInInfo.setRowId( "ZSRK" + MD5Utils.md5( scfRenewableInInfo.getRenewableInNum()));
        // 设置登记日期
        scfRenewableInInfo.setRecordDate(formatdate);
        // 设置登记时间
        scfRenewableInInfo.setRecordTime(formTime);
        // 设置默认已付金额为0
        scfRenewableInInfo.setPaidAmount(new BigDecimal("0"));
        // 补充对象字段结束end
        List<String> rowIds = scfRenewableInInfo.getRowIds();
        // 开始关联支付回单
        List<RenewableInByPayment> renewableInByPayments = scfRenewableInInfo.getRenewableInByPayments();
        if (renewableInByPayments != null) {
            // 获取支付回单关联的信息
            for (RenewableInByPayment renewableInByPayment : renewableInByPayments) {
                // 设置再生资源入库单号码
                renewableInByPayment.setRenewableInNum(scfRenewableInInfo.getRenewableInNum());
                // 设置再生资源入库单编号rowId
                renewableInByPayment.setRenewableRowId(scfRenewableInInfo.getRowId());
                // 判断是否输入了使用金额--如果未输入则抛出一个异常提示
                if (renewableInByPayment.getUseAmount() == null) {
                    throw new NullPointerException("请输入使用金额！");
                }
                // 获取当前支付回单的当前剩余金额
                BigDecimal remainAmountByPaymentNum = scfPaymentInfoMapper.selectAmountByPaymentNum(renewableInByPayment.getPaymentNum());
                // 判断输入的使用金额是否大于当前剩余金额
                if (renewableInByPayment.getUseAmount().compareTo(remainAmountByPaymentNum) > 0) {
                    throw new IllegalArgumentException("输入的使用金额大于支付回单剩余金额，请重新输入！");
                }
                // 设置支付回单的rowId
                renewableInByPayment.setPaymentRowId(renewableInByPayment.getRowId());
                // 设置支付回单关联关系的记录编号

                renewableInByPayment.setRowId( "ZSRK" + MD5Utils.md5(scfRenewableInInfo.getRowId() + renewableInByPayment.getPaymentNum()  ));

                // 获取回单使用金额
                BigDecimal useAmount = renewableInByPayment.getUseAmount();
                // 获取初始已付金额
                BigDecimal paidAmountInit = scfRenewableInInfo.getPaidAmount();
                // 将回单使用金额加初始已付金额运算后设置进再生入库单的已付金额中
                // 将 useAmount 和 paidAmountInit 相加
                BigDecimal totalPaidAmount = paidAmountInit.add(useAmount);
                // 设置新的已付金额
                scfRenewableInInfo.setPaidAmount(totalPaidAmount);
                // 初始化支付状态，默认为暂未支付
                String paymentStatus = "0";
                // 获取再生资源入库的总金额
                BigDecimal amount = scfRenewableInInfo.getAmount();
                // 判断支付状态
                if (totalPaidAmount.compareTo(BigDecimal.ZERO) > 0) {
                    if (totalPaidAmount.compareTo(amount) < 0) {
                        // 如果已付小于总额，则设置为部分支付
                        paymentStatus = "1";
                    } else if (totalPaidAmount.compareTo(amount) == 0) {
                        // 如果已付等于总额，则设置为全部支付
                        paymentStatus = "2";
                    } else if (totalPaidAmount.compareTo(amount) > 0) {
                        // 如果已付金额大于入库单金额，则抛出异常
                        throw new IllegalArgumentException("支付回单输入的使用金额超过入库单金额，请重新输入！");
                    }
                    // 如果已付总额等于0，保持为暂未支付
                }
                // 将支付状态设置到再生资源入库单
                scfRenewableInInfo.setPaySts(paymentStatus);
                // 存储利废入库单与支付回单的关联关系
                baseMapper.saveRenewableInByPayment(renewableInByPayment.getRowId(), renewableInByPayment.getRenewableInNum(), renewableInByPayment.getRenewableRowId(), renewableInByPayment.getPaymentNum(),
                        renewableInByPayment.getPaymentRowId(), renewableInByPayment.getUseAmount() ,scfRenewableInInfo.getOrgCode());
                // 开始更新支付回单状态及剩余金额
                // 将获取到的支付回单剩余金额减去新使用的金额
                // 将 remainAmountByPaymentNum 和 useAmount 相减
                BigDecimal totalAmount = remainAmountByPaymentNum.subtract(useAmount);
                // 获取支付回单的总面值
                BigDecimal amountByPaymentNum = scfPaymentInfoMapper.selectAmountByPaymentNum(renewableInByPayment.getPaymentNum());
                // 判断支付回单的使用状态
                String usageStatus;
                // 使用 compareTo 方法比较剩余金额和回单金额的大小关系
                int comparisonResult = totalAmount.compareTo(amountByPaymentNum);
                if (comparisonResult == 0) {
                    // 如果剩余金额等于回单金额，则设置为暂未使用
                    usageStatus = "0";
                } else if (comparisonResult < 0 && totalAmount.compareTo(BigDecimal.ZERO) != 0) {
                    // 如果剩余金额小于回单金额并大于0，则设置为部分使用
                    usageStatus = "1";
                } else {
                    // 如果剩余金额等于0，则设置为全部使用
                    usageStatus = "2";
                }
                // 同步更新对应回单的剩余金额及支付状态
                scfPaymentInfoMapper.updateRemainAmountAndSseStsZSRK_REMAIN_AMOUNT(renewableInByPayment.getPaymentNum(), totalAmount, usageStatus);
            }
        }
        boolean isSave = save(scfRenewableInInfo);
        // 设置再生资源入库单文件存放路径
        String path = "ZSRK" + "/" +  "ZSRK" + MD5Utils.md5( scfRenewableInInfo.getRenewableInNum()) + "/";
        if (rowIds != null) {
            if (!rowIds.isEmpty()) {
                if (isSave) {
                    for (String fileRowId : rowIds) {
                        // 根据文件id获取文件的临时objectKey
                        String objectKeyOfTemp = scfFileAttachmentInfoService.getFilePath(fileRowId,null);
                        // 截取文件的名称
                        String extractFileName = obsUtil.extractFileName(objectKeyOfTemp);
                        // 拼接正式的objectKey
                        String objectKey = path + extractFileName;
                        obsUtil.copyFile(objectKey, objectKeyOfTemp);
                        scfFileAttachmentInfoService.updateFilePath(fileRowId, objectKey);
                    }
                }
                scfFileAttachmentInfoService.batchUpdateField(rowIds,  "ZSRK" + MD5Utils.md5( scfRenewableInInfo.getRenewableInNum()));
            }
        }
        // 生成日期时间
        SimpleDateFormat datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = datetime.format(new Date());
        ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
        // 根据用户id查询用户名称，重新赋值登记人字段
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(scfRenewableInInfo.getRecorder()));
        scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
        scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.LOGISTICS.getOperation());
        scfOperationLogInfo.setOperationFunction("再生资源入库单");
        scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.ADD.getOperation());
        scfOperationLogInfo.setOperationContent("新增一条再生资源入库单，再生资源入库单号：" + scfRenewableInInfo.getRenewableInNum());
        scfOperationLogInfo.setRecordDate(formattedDateTime);
        // 判断再生入库单是否新增成功
        if (isSave) {
            // 成功则同步记录操作日志记录
            scfOperationLogInfoService.saveOperationLogInfo(scfOperationLogInfo);
        }
        return isSave;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int bachSaveRemewableInInfo(List<ScfRenewableInInfo> scfRenewableInInfos, String operatorId) {
        List<ScfRenewableInInfo> scfRenewableInInfoList = new ArrayList<>();
        for (ScfRenewableInInfo scfRenewableInInfo : scfRenewableInInfos) {
            // 设置登记人ID
            scfRenewableInInfo.setRecorder(operatorId);
            // 设置已付金额默认为0
            scfRenewableInInfo.setPaidAmount(BigDecimal.valueOf(0));
            // 设置支付状态默认为0.未支付
            scfRenewableInInfo.setPaySts("0");
            // 生成日期
            SimpleDateFormat date = new SimpleDateFormat("YYYYMMdd");
            String formatdate = date.format(new Date());
            // 生成时间
            SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
            String formTime = timeFormat.format(new Date());

            // 设置登记日期
            scfRenewableInInfo.setRecordDate(formatdate);
            // 设置登记时间
            scfRenewableInInfo.setRecordTime(formTime);
            // 设置默认已付金额为0
            scfRenewableInInfo.setPaidAmount(new BigDecimal("0"));
            // 补充对象字段结束end
            // 判断是否已存在该再生入库单号码
//            String renewableInNum = scfRenewableInInfo.getRenewableInNum();
//            String rowIdByRenewableInNum = baseMapper.selectRowIdByRenewableInNum(renewableInNum);


            // 开始补充对象字段start
            // 设置记录编号
            scfRenewableInInfo.setRowId( "ZSRK" + MD5Utils.md5( scfRenewableInInfo.getRenewableInNum()));

            scfRenewableInInfoList.add(scfRenewableInInfo);
        }
        if(!scfRenewableInInfoList.isEmpty()){
            baseMapper.saveBatchRenewableInList(scfRenewableInInfoList);
        }


        return scfRenewableInInfoList.size();
    }

    /**
     * 再生资源入库单更新
     *
     * @param scfRenewableInInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRemewableInInfo(ScfRenewableInInfoDTO scfRenewableInInfo) {
        // 开始补充对象字段start
        // 补充对象字段结束end
        String rowId = scfRenewableInInfo.getRowId();
        List<String> rowIds = scfRenewableInInfo.getRowIds();
        // 生成日期时间
        SimpleDateFormat datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = datetime.format(new Date());
        // 生成日期
        SimpleDateFormat date = new SimpleDateFormat("YYYYMMdd");
        String formatdate = date.format(new Date());
        // 生成时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
        String formTime = timeFormat.format(new Date());
        // 判断更新入库单时是否有旧的关联关系
        List<RenewableInByPayment> renewableInByPaymentsOld = baseMapper.selectRenewableInByPayment(scfRenewableInInfo.getRenewableInNum());
        if (renewableInByPaymentsOld != null && !renewableInByPaymentsOld.isEmpty()) {
            for (RenewableInByPayment renewableInByPayment : renewableInByPaymentsOld) {
                // 如果存在则获取关联关系表中该支付回单使用了多少金额
                String paymentNum = renewableInByPayment.getPaymentNum();
                BigDecimal remainAmountByPaymentNum = scfPaymentInfoMapper.selectAmountByPaymentNum(paymentNum);
                BigDecimal useAmount = renewableInByPayment.getUseAmount();
                // 计算使用金额加上支付回单剩余金额
                BigDecimal totalAmount = remainAmountByPaymentNum.add(useAmount);
                // 获取支付回单面值
                BigDecimal amountByPaymentNum = scfPaymentInfoMapper.selectAmountByPaymentNum(paymentNum);
                // 判断
                String usageStatus;
                // 使用 compareTo 方法比较剩余金额和回单金额的大小关系
                int comparisonResult = totalAmount.compareTo(amountByPaymentNum);

                if (comparisonResult == 0) {
                    // 如果剩余金额等于回单金额，则设置为暂未使用
                    usageStatus = "0";
                } else if (comparisonResult < 0 && totalAmount.compareTo(BigDecimal.ZERO) != 0) {
                    // 如果剩余金额小于回单金额并大于0，则设置为部分使用
                    usageStatus = "1";
                } else {
                    // 如果剩余金额等于0，则设置为全部使用
                    usageStatus = "2";
                }
                // 更新支付回单中的剩余金额及使用状态
                scfPaymentInfoMapper.updateRemainAmountAndSseStsZSRK_REMAIN_AMOUNT(paymentNum, totalAmount, usageStatus);
            }
        }
        // 清理旧的关联关系记录，然后建立新的关联关系
        baseMapper.deleteRenewableInByPayment(scfRenewableInInfo.getRenewableInNum());
        // 清理旧关联关系后，设置该入库单支付金额为0
        scfRenewableInInfo.setPaidAmount(new BigDecimal("0"));
        // 初始化支付状态，默认为暂未支付
        String paymentStatus = "0";
        scfRenewableInInfo.setPaySts(paymentStatus);
        // 开始关联支付回单
        List<RenewableInByPayment> renewableInByPayments = scfRenewableInInfo.getRenewableInByPayments();
        if (renewableInByPayments != null) {
            // 获取支付回单关联的信息
            for (RenewableInByPayment renewableInByPayment : renewableInByPayments) {
                // 设置入库单号码
                renewableInByPayment.setRenewableInNum(scfRenewableInInfo.getRenewableInNum());
                renewableInByPayment.setRenewableRowId(scfRenewableInInfo.getRowId());
                renewableInByPayment.setPaymentRowId(renewableInByPayment.getRowId());
                if (renewableInByPayment.getUseAmount() == null) {
                    throw new NullPointerException("请输入使用金额！");
                }
                // 设置支付回单关联关系的rowId为再生资源入库单的id
                renewableInByPayment.setRowId( "ZSRK" + MD5Utils.md5(scfRenewableInInfo.getRowId() + renewableInByPayment.getPaymentNum()  ));
                // 获取回单使用金额
                BigDecimal useAmount = renewableInByPayment.getUseAmount();
                // 获取初始已付金额
                BigDecimal paidAmountInit = scfRenewableInInfo.getPaidAmount();
                // 将回单使用金额加初始已付金额运算后设置进再生入库单的已付金额中
                // 将 useAmount 和 paidAmountInit 相加
                BigDecimal totalPaidAmount = paidAmountInit.add(useAmount);
                // 设置新的已付金额
                scfRenewableInInfo.setPaidAmount(totalPaidAmount);
                // 获取再生资源入库单的已付金额
                BigDecimal paidAmount = scfRenewableInInfo.getPaidAmount();
                // 获取再生资源入库的总金额
//                这个地方用 结算金额
//                BigDecimal amount = scfRenewableInInfo.getAmount();
                BigDecimal amount = scfRenewableInInfo.getSettlementAmount();
                // 判断支付状态
                if (paidAmount.compareTo(BigDecimal.ZERO) > 0) {
                    if (paidAmount.compareTo(amount) < 0) {
                        // 如果已付小于总额，则设置为部分支付
                        paymentStatus = "1";
                    } else if (paidAmount.compareTo(amount) == 0) {
                        // 如果已付等于总额，则设置为全部支付
                        paymentStatus = "2";
                    } else if (totalPaidAmount.compareTo(amount) > 0) {
                        // 如果已付金额大于入库单金额，则抛出异常
                        throw new RuntimeException("支付回单输入的使用金额超过入库单金额");
                    }
                    // 如果已付总额等于0，保持为暂未支付
                }
                // 将支付状态设置到再生资源入库单
                scfRenewableInInfo.setPaySts(paymentStatus);
//                设置 再生入库的关联表


                baseMapper.saveRenewableInByPayment(renewableInByPayment.getRowId(), renewableInByPayment.getRenewableInNum(), renewableInByPayment.getRenewableRowId(),
                        renewableInByPayment.getPaymentNum(), renewableInByPayment.getPaymentRowId(), renewableInByPayment.getUseAmount() ,scfRenewableInInfo.getOrgCode());
                // 获取当前支付回单的当前剩余金额
                BigDecimal remainAmountByPaymentNum = scfPaymentInfoMapper.selectAmountByPaymentNum(renewableInByPayment.getPaymentNum());
                // 将上一步获取到的金额加上新使用的金额
                // 将 remainAmountByPaymentNum 和 useAmount 相加
                BigDecimal totalAmount = remainAmountByPaymentNum.subtract(useAmount);
                // 获取支付回单的总面值
                BigDecimal amountByPaymentNum = scfPaymentInfoMapper.selectAmountByPaymentNum(renewableInByPayment.getPaymentNum());
                // 判断
                String usageStatus;
                // 使用 compareTo 方法比较剩余金额和回单金额的大小关系
                int comparisonResult = totalAmount.compareTo(amountByPaymentNum);

                if (comparisonResult == 0) {
                    // 如果剩余金额等于回单金额，则设置为暂未使用
                    usageStatus = "0";
                } else if (comparisonResult < 0 && totalAmount.compareTo(BigDecimal.ZERO) != 0) {
                    // 如果剩余金额小于回单金额并大于0，则设置为部分使用
                    usageStatus = "1";
                } else {
                    // 如果剩余金额等于0，则设置为全部使用
                    usageStatus = "2";
                }
                // 同步更新对应回单的剩余金额及支付状态
                scfPaymentInfoMapper.updateRemainAmountAndSseStsZSRK_REMAIN_AMOUNT(renewableInByPayment.getPaymentNum(), totalAmount, usageStatus);
            }
        }
        // 设置再生资源入库单文件存放路径
        String path = "RWRK" + "/" + rowId + "/";
        if (rowIds != null) {


            if (!rowIds.isEmpty()) {
                if (rowId != null) {
                    // 取消旧文件与记录关联
                    scfFileAttachmentInfoService.updataFiledNull(rowId);
                    // 给上传的新文件添加关联编号
                    scfFileAttachmentInfoService.batchUpdateField(rowIds, rowId);
                    for (String fileRowId : rowIds) {
                        // 根据文件id获取文件的临时objectKey
                        String objectKeyOfTemp = scfFileAttachmentInfoService.getFilePath(fileRowId,null);
                        // 截取文件的名称
                        String extractFileName = obsUtil.extractFileName(objectKeyOfTemp);
                        // 拼接正式的objectKey
                        String objectKey = path + extractFileName;
                        Boolean aBoolean = obsUtil.copyFile(objectKey, objectKeyOfTemp);
                        if(aBoolean){
                            scfFileAttachmentInfoService.updateFilePath(fileRowId, objectKey);
                        }

                    }
                }
            }
        }
        boolean update = updateById(scfRenewableInInfo);
/*        // 记录操作日志
        ScfOperationLogInfo scfOperationLogInfo = new ScfOperationLogInfo();
        scfOperationLogInfo.setRowId("Log" + formatdate + formTime + localCacheIdGenerator.nextId());
        // 根据用户id查询用户名称，重新赋值登记人字段
        List<Long> ids = new ArrayList<>();
        ids.add(Long.valueOf(scfRenewableInInfo.getRecorder()));
        scfOperationLogInfo.setRecorder(userService.selectUserNameByIds(ids).get(0));
        scfOperationLogInfo.setOperationModule(ScfOperationLogInfoEnum.LOGISTICS.getOperation());
        scfOperationLogInfo.setOperationFunction("再生资源入库单");
        scfOperationLogInfo.setOperationType(ScfOperationLogInfoEnum.UPDATE.getOperation());
        scfOperationLogInfo.setOperationContent("更新一条再生资源入库单，再生资源入库单号：" + scfRenewableInInfo.getRenewableInNum());
        scfOperationLogInfo.setRecordDate(formattedDateTime);
        // 判断更新记录是否成功
        if (update) {
            // 成功，则同步记录操作日志
            scfoperationloginfoservice.saveoperationloginfo(scfoperationloginfo);
        }*/
        return update;
    }

    /**
     * 再生资源入库单批量导入
     *
     * @param operatorId
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public List<ScfRenewableInInfo> batchSaveRenewableInInfo(String operatorId, MultipartFile file) throws IOException {
        // 获取文件的Base64编码
        byte[] fileBytes = file.getBytes();
        // 解析excel文件获取数据集合
        List<ScfRenewableInInfo> scfRenewableInInfos = ExcelUtil.readExcel(fileBytes, ScfRenewableInInfo.class, "再生资源企业入库单", 3);
        log.info("数据集合为：{}", scfRenewableInInfos);
        return scfRenewableInInfos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(String[] ids) {

        baseMapper.deleteSalesByIds(ids );
        return this.baseMapper.deleteByIds(ids);
    }
}
